#include "stdafx.h"
//-------------------------------------------------------------------------------------------------
//ImageObjectType.cpp  - Type of Object found in Image: (abstract base class)               
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk July 2011
//
//----Comments-------------------------------------------------------------------------------------
//
// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the IMAGEPROCLIB_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// IMAGEPROCLIBAPI functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
//--------------------------------------------------------------------------------------------------

#include <stdlib.h>

#include "ImageObjectType.h"
#include "SelectType.h"
#include "PtShapeType.h"
#include "PtAnnotateShapeType.h"
#include "EllipseShapeType.h"

#include "ImageType.h"

const char * const ImageObjectType::attribClassName = "Base";
const char * const ImageObjectType::defaultPenColour = "255:255:255";

ImageObjectType::ImageObjectType(void) :
	_PenCOLORREF(0),
	_InvPenCOLORREF(0),
	_Emax(0),
	_ResourceId(-1)
{
	_Name[0] = '\0';
	_Code[0] = '\0';
	_PenColour[0] = '\0';
	_MenuName[0] = '\0';
}


ImageObjectType::~ImageObjectType(void)
{
	ClearAllLists();
}

ImageObjectType *ImageObjectType::CreateImageObjectType(TiXmlElement *xmlImageObjectType, ResourceList &resourceList)
{
	ImageObjectType *rc = '\0';
	
	const char *baseType = (xmlImageObjectType == '\0') ? SelectType::baseClassName : xmlImageObjectType->Attribute("Base");

		
	int	resourceID = -1;						//resource IDs for each ImageObjectType are initializied in ArchiveProcGUIDoc::m_ResourceIDList
	if ( (baseType != '\0') && (strcmp (baseType, SelectType::baseClassName) == 0 ))
	{
		if((resourceID = resourceList.GetNewResourceId(SelectType::baseClassName)) != -1)
			rc = new SelectType(resourceID);
	}
																			
	if ( (baseType != '\0') && (strcmp (baseType, PtShapeType::baseClassName) == 0 ))
	{
		if((resourceID = resourceList.GetNewResourceId(PtShapeType::baseClassName)) != -1)		//there must be a string in resources for each different PtShapeType; IDS_PTSHAPETYPE_1, ..., IDS_PTSHAPETYPE_10
			rc = new PtShapeType(xmlImageObjectType, resourceID);
	}

	if ( (baseType != '\0') && (strcmp (baseType, PtAnnotateShapeType::baseClassName) == 0 ))
	{
		if((resourceID = resourceList.GetNewResourceId(PtAnnotateShapeType::baseClassName)) != -1)		//there must be a string in resources for each different EllipseType; IDS_ELLIPSETYPE_1, ..., IDS_ELLIPSETYPE_10
			rc = new PtAnnotateShapeType(xmlImageObjectType, resourceID);
	}
	
	if ( (baseType != '\0') && (strcmp (baseType, EllipseShapeType::baseClassName) == 0 ))
	{
		if((resourceID = resourceList.GetNewResourceId(EllipseShapeType::baseClassName)) != -1)		//there must be a string in resources for each different EllipseType; IDS_ELLIPSETYPE_1, ..., IDS_ELLIPSETYPE_10
			rc = new EllipseShapeType(xmlImageObjectType, resourceID);
	}



	if ( rc != '\0')
		rc->AddProperties(FindImageTypeImageObjectProperties (xmlImageObjectType));			//add properties for this type of ImageObject

	return rc;
}

void ImageObjectType::SetPenColour( const char *colour)
{ 
	BYTE component[3]  = {0,0,0};

	int index = 0;
	int start = 0;
	int end = 0;
	while( (end < (PEN_COLOUR_LEN+1)) && (index < 3))
	{
		if ( (*(colour+end) != ':') && (*(colour+end) != '\0'))
			_PenColour[end-start] = *(colour+end);
		else
		{
			_PenColour[end-start] = '\0';
			component[index++] = atoi(_PenColour);
			if (*(colour+end) == '\0')
				break;
			start = end+1;
		}
		end++;
	}
	if ((index != 3) || (end > PEN_COLOUR_LEN))
	{
		_PenCOLORREF = RGB(255, 255, 255);
		_InvPenCOLORREF = RGB(0, 0, 0);
		strcpy(_PenColour, "255:255:255" );
	}
	else
	{
		_PenCOLORREF = RGB(component[0], component[1], component[2]);
		_InvPenCOLORREF = RGB(255-component[0], 255-component[1], 255-component[2]);
		strncpy(_PenColour, colour, end );
		_PenColour[end] = '\0'; 
	}
	return;
}

ImageTypeProp *ImageObjectType::LookupProperty (const char *name)
{
	ImageTypeProp *rc = '\0';

	if ( name != '\0' )
	{
		std::string propName = name;
		size_t cnt = _ImageTypeProps.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (propName == _ImageTypeProps[x]->GetName() )
			{
				rc = _ImageTypeProps[x];
				break;
			}
		}
	}
	return rc;
}

//............................................................................................
//private member functions
//............................................................................................

void ImageObjectType::AddProperties(TiXmlElement *xmlImageTypeImageObjects)
{
	if (xmlImageTypeImageObjects != '\0')
	{
		for( TiXmlNode *child = xmlImageTypeImageObjects->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *xmlImageTypeProp = dynamic_cast<TiXmlElement *>(child);
				if ( xmlImageTypeProp != '\0' )
				{
					ImageTypeProp *pImageTypeProp = '\0';
					std::string ImageTypePropName = xmlImageTypeProp->Value();
					if ( ImageTypePropName == ImageType::xmlImageTypeProp)
					{
						if ( (pImageTypeProp = ImageTypeProp::CreateImageTypeProp(xmlImageTypeProp, ImageType::xmlImageType)) != '\0')
						{
							if ( AddProperty(pImageTypeProp) == false)
								delete pImageTypeProp;
						}
					}
				}
			}
		}
	}
}

bool ImageObjectType::AddProperty (ImageTypeProp *pImageTypeProp )
{
	bool rc = false;

	if ( LookupProperty(pImageTypeProp->GetName()) == '\0')
	{
		_ImageTypeProps.push_back(pImageTypeProp);
		rc = true;
	}

	return rc;

}

TiXmlElement *ImageObjectType::FindImageTypeImageObjectProperties (TiXmlElement *pImageTypeImageObjectXml)
{
	TiXmlElement *pImageTypeImageObjectPropsXml = '\0';

	if ( pImageTypeImageObjectXml != '\0')
	{
		for( TiXmlNode *child = pImageTypeImageObjectXml->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *ImageTypeImageObjectPropsXml = dynamic_cast<TiXmlElement *>(child);
				if ( ImageTypeImageObjectPropsXml != '\0' )
				{
					std::string name = ImageTypeImageObjectPropsXml->Value();
					if ( name == ImageType::xmlImageTypeProps)
					{
						pImageTypeImageObjectPropsXml = ImageTypeImageObjectPropsXml;
					}
				}
			}
		}
	}
	return pImageTypeImageObjectPropsXml;
}

bool	ImageObjectType::ClearAllLists()
{
	bool rc = false;

	size_t	cnt = _ImageTypeProps.size();
	if (cnt > 0 )
	{
		rc = false;
		for (size_t x = 0; x < cnt; x++)
			delete _ImageTypeProps[x];
		_ImageTypeProps.clear();
		rc = true;
	}
	return rc;
}

//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------
